package org.lib93.com.libSkin.lifecycle

import android.annotation.SuppressLint
import android.app.Activity
import android.app.Application
import android.os.Build
import android.os.Bundle
import android.view.LayoutInflater
import androidx.core.view.LayoutInflaterCompat
import org.lib93.com.libSkin.SkinManager
import org.lib93.com.libSkin.SkinThemeManager
import org.lib93.com.libSkin.facctory.SkinFactory2
import org.lib93.com.libSkin.utils.SkinPreference
import java.util.*

/**
 * activity 和 fragment生命周期创建监测，和收集页面view有关系
 * 每个页面加载解析都会调用createViewFromTag
 * 通过自定义Factory2 进行拦截设置
 */
class ApplicationActivityLifecycle constructor(private val observable:Observable /**被观察者**/): Application.ActivityLifecycleCallbacks {
    private var factory2Map = mutableMapOf<Activity,SkinFactory2>() //每个页面对应一个factory2
    @SuppressLint("SoonBlockedPrivateApi")
    override fun onActivityCreated(p0: Activity, p1: Bundle?) {
        SkinThemeManager.getInstance().updateStatusBarColor(p0)//加载一个界面更改一次主题
        //页面调用 onCreate后
        //设置自定义的factory2
        val layoutInflater = p0.layoutInflater
        var factory2 = SkinFactory2(p0)
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) {
            //setFactory2 方法中含有 mFactorySet这个属性 限制factory2只能设置一次 需要改掉这个参数
            val declaredField = LayoutInflater::class.java.getDeclaredField("mFactorySet")
            declaredField.isAccessible = true
            declaredField.setBoolean(layoutInflater,false)
            //  layoutInflater.factory2 = factory2
            ///下面的方法自带版本适配
            //有限制     if (Build.VERSION.SDK_INT < 21) 才执行
            LayoutInflaterCompat.setFactory2(layoutInflater,factory2)

        }else{
          //  解决mFactorySet在Android Q中被非SDK接口限制的问题
              //  https://blog.csdn.net/qq_25412055/article/details/100033637?spm=1001.2101.3001.6661.1&utm_medium=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-1.pc_relevant_default&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-1.pc_relevant_default&utm_relevant_index=1
            //收集所有的factory2
            //有限制     if (Build.VERSION.SDK_INT < 21) 才执行
//            LayoutInflaterCompat.setFactory2(layoutInflater,factory2)
    //绕过21这个限制直接反射执行    内层函数    forceSetFactory2(inflater, (LayoutInflater.Factory2) f);
            forceSetFactory2(layoutInflater,p0)
        }
        factory2Map.put(p0,factory2)
        //给被观察者添绑定观察者
        observable.addObserver(factory2)

    }

    private fun forceSetFactory2(inflater: LayoutInflater,p0: Activity) {
        val compatClass = LayoutInflaterCompat::class.java
        val inflaterClass = LayoutInflater::class.java
        try {
            val sCheckedField = compatClass.getDeclaredField("sCheckedField")
            sCheckedField.setAccessible(true)
            sCheckedField.setBoolean(inflater, false)
            val mFactory = inflaterClass.getDeclaredField("mFactory")
            mFactory.setAccessible(true)
            val mFactory2= inflaterClass.getDeclaredField("mFactory2")
            mFactory2.setAccessible(true)
            val factory = SkinFactory2(p0)
//            if (inflater.factory2 != null) {
//                factory.setInterceptFactory2(inflater.factory2)
//            } else if (inflater.factory != null) {
//                factory.setInterceptFactory(inflater.factory)
//            }
            mFactory2.set(inflater, factory)
            mFactory.set(inflater, factory)
        } catch (e: IllegalAccessException) {
            e.printStackTrace()
        } catch (e: NoSuchFieldException) {
            e.printStackTrace()
        }
    }
    override fun onActivityStarted(p0: Activity) {

    }

    override fun onActivityResumed(p0: Activity) {

    }

    override fun onActivityPaused(p0: Activity) {

    }

    override fun onActivityStopped(p0: Activity) {

    }

    override fun onActivitySaveInstanceState(p0: Activity, p1: Bundle) {

    }

    override fun onActivityDestroyed(p0: Activity) {
        val observer= factory2Map.remove(p0)
        SkinManager.getInstance(p0.application).deleteObserver(observer)
    }
}